package com.msconfig.mvp.view.fragment;
/*
 * author: caojunhao
 * date  : 2020/4/28
 * desc  :通讯设置页面
 */

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.geo.msconfig.R;
import com.msconfig.bluetooth.BlueToothInit;
import com.msconfig.bluetooth.IBlueToothDeviceFoundListener;
import com.msconfig.bluetooth.IBlueToothOperateListener;
import com.msconfig.bluetooth.IBondStateListener;
import com.msconfig.broadcast.BlueToothBroadcastReceiver;
import com.msconfig.device.DeviceManage;
import com.msconfig.event.BluetoothInfoEvent;
import com.msconfig.event.DeviceUpdateEvent;
import com.msconfig.event.ShowDeviceNameEvent;
import com.msconfig.mvp.view.activity.base.BaseMvpFragment;
import com.msconfig.mvp.view.activity.base.BasePresenter;
import com.msconfig.mvp.view.adapter.BlueToothDeviceAdapter;
import com.msconfig.utils.SpUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import static android.view.View.VISIBLE;
import static com.msconfig.bluetooth.BlueToothInit.PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION;
import static com.msconfig.mvp.view.activity.MainActivity.ISCLICKCANNEL;
import static com.msconfig.mvp.view.activity.MainActivity.ISFRAGMENT;

public class EquipmentCommunicationSetupFragment extends BaseMvpFragment implements View.OnClickListener{
    private Button btnConnectServer;
    private Button btnDisconnectServer;
    private Button btnSearchBlueTooth;
    private Button btnStopSearchBlueTooth;
    private Button btnGiveupBond;//取消配对
    private TextView tvCommonTitle;
    private TextView tvDeviceName;
    private TextView tvLoading;
    private ImageView ivCommonBack;
    private ImageView ivSwitchOpenBluetoothOn;
    private ImageView ivSwitchOpenBluetoothOff;
    private ImageView ivLoading;
    private FrameLayout flLoading;
    private ListView listView;

    private BlueToothInit operateBlueTooth;
    private Animation searchAnim;
    private Animation connectAnim;
    private BlueToothDeviceAdapter adapter;
    private BluetoothAdapter mBtAdatper;
    private BlueToothBroadcastReceiver blueToothBroadcastReceiver;
    private BluetoothDevice device;
    private int rssi;
    public HashSet<BluetoothDevice> sets=new HashSet<>();
    public Set<BluetoothDevice> bondedDevices;
    public static final String LAST_DEVICE ="lastDevice";
    private Context context;
    private SimpleDateFormat simpleDateFormat;
    private Date date;
    private MyHandler myHandler;
    private ConnectioningDialogFragment connectioningDialogFragment;
    private Activity activity;
    protected static final int MSG_GET_RTK_DEFAIL =1;//自动连接
    private boolean isGetRTKSucc=false;
    private boolean isClickBtnConnectServer;
    private LocationManager locManager;


    private static class MyHandler extends Handler {
        WeakReference<EquipmentCommunicationSetupFragment> weakReference;

        private MyHandler(EquipmentCommunicationSetupFragment fragment) {
            weakReference = new WeakReference<EquipmentCommunicationSetupFragment>(fragment);
        }
        @Override
        public void handleMessage(Message msg) {
            EquipmentCommunicationSetupFragment fragment = weakReference.get();
            if (fragment != null) {
                switch (msg.what){
                    case MSG_GET_RTK_DEFAIL://GETALL节点数据一直没有返回
                        fragment.whenReadRtkDefail();
                        break;
                }
            }
        }
    }

    //连接成功或者失败.当进入这个页面进行连接时，不让MainActivity接收事件，只在这里接收事件,
    // 通过设置变量ISFRAGMENT判断是哪个页面进行的连接
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void showDeviceConnectResultStatus(DeviceUpdateEvent.DeviceConnectResultStatus event) {
        if(event.isbSuccess()){
            //连接服务器成功
            whenConnectToServerSuccess();
        }else{
            //连接服务器失败
            whenConnecToServerDefail();
        }
    }

    //GETALL数据成功返回，这才是表示最终真正连接成功
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void showGetRtkResultStatus(DeviceUpdateEvent.UpdateDialogGetRtkSuccessStatus event) {
        whenReadRtkSuccess();
    }

    //断开设备
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void showDeviceDisConnectResultStatus(DeviceUpdateEvent.DeviceDisConnectResultStatus event) {
        whenDeviceDisConnect();
    }

//    //自动连接--只在MainActivity做处理
//    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
//    public void whenAutoConnect(DeviceUpdateEvent.AutoConnectEvent event) {
//        if(!SpUtils.obtain().getBoolean(ISFRAGMENT,false))
//            return;
//        //蓝牙没有打开
//        if (!mBtAdatper.isEnabled()) {
//            return;
//        }
//        date = new Date();
//        GeneralUtil.writeMessageToFile(simpleDateFormat.format(date) + "正在自动重连......（设备："+device.getName()+")\r\n",debugName);
//        connectToServer();
//    }

    //连接服务器成功，1.告诉设置页面 2.对话框状态显示
    private void whenConnectToServerSuccess(){
        if(connectioningDialogFragment!=null){
            //string不使用getResource这种方式，因为当在这个页面显示了对话框之后退出到MainActivity，那么attach之间就断了，getResource为空空指针
            connectioningDialogFragment.setProgress(50,"正在获取RTK状态......");
        }
        myHandler.sendEmptyMessageDelayed(MSG_GET_RTK_DEFAIL,9000);
    }

    //读取RTK信息成功 1.告诉设置页面 2更新对话框状态 3.保存当前连接成功的设备的信息，方便下次自动重连
    private void whenReadRtkSuccess() {
        isGetRTKSucc=true;
        date = new Date();
        if(connectioningDialogFragment!=null && connectioningDialogFragment.isVisible()){
            connectioningDialogFragment.setProgress(100,"连接成功......");
            connectioningDialogFragment.dismissAllowingStateLoss();

        }
        //连接成功
        //发送蓝牙的强度和地址给那边
        EventBus.getDefault().postSticky(new BluetoothInfoEvent(device));
        btnSearchBlueTooth.setVisibility(View.GONE);
        btnDisconnectServer.setVisibility(VISIBLE);
        btnConnectServer.setVisibility(View.GONE);
//        //保存最后一次连接的设备
        if (device != null) {
            tvDeviceName.setText(device.getName());
            EventBus.getDefault().postSticky(new ShowDeviceNameEvent(device));
            SpUtils.obtain().save(LAST_DEVICE, device.getAddress());
        }
        //只有本页面的连接才返回主界面
        if(isClickBtnConnectServer){
            backTo();
        }
    }

    //连接服务器失败 1.告诉设置页面 2.对话框消失 3.断开服务器
    private void whenConnecToServerDefail() {
        //主页点击取消连接时，进入这个页面还会有显示连接失败的事件过来，在这里屏蔽掉
        if(SpUtils.obtain().getBoolean(ISCLICKCANNEL,false)) {
            SpUtils.obtain().save(ISCLICKCANNEL,false);
            return;
        }
        dismissDialog();
        showToast(R.string.toasst_connect_fail);
    }

    //读取RTK信息失败，因为不知道怎么判断，采用大概8s没有连接，就表示读取RTK失败
    //1.消失对话框 2.断开连接
    private void whenReadRtkDefail() {
        if(isGetRTKSucc){
            isGetRTKSucc=false;
            return;
        }
        //这种情况也不需要自动连接
        DeviceManage.getInstance().setAutoDisconnect(false);
        DeviceManage.getInstance().disConnect();
        showToast(R.string.toast_read_rtk_defail);
        dismissDialog();
        btnConnectServer.setEnabled(true);
    }

    //断开连接
    private void whenDeviceDisConnect() {
        dismissDialog();
        whenOnClickDisconnect();
    }


    public static EquipmentCommunicationSetupFragment newInstance() {
        Bundle args = new Bundle();
        EquipmentCommunicationSetupFragment fragment = new EquipmentCommunicationSetupFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    protected void initData() {
        tvCommonTitle.setText(R.string.title_connection_setup);
        locManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        btnConnectServer.setEnabled(true);
        myHandler =new MyHandler(this);
        simpleDateFormat=new SimpleDateFormat("yyyy/MM/dd HH:mm");
        mBtAdatper = BluetoothAdapter.getDefaultAdapter();
        adapter = new BlueToothDeviceAdapter(getContext(), R.layout.layout_bluetooth_device_list_item);
        operateBlueTooth= new BlueToothInit(this,getContext(),mBtAdatper, adapter);
        listView.setAdapter(adapter);
        registerBlueToothReceiver();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                adapter.setCurrentItem(position);
                adapter.setmIsClick(true);
                adapter.notifyDataSetChanged();
                device = (BluetoothDevice) parent.getItemAtPosition(position);
            }
        });

        //判断蓝牙按钮是否打开
        if(operateBlueTooth.isOpenBlueTooth()){
            whenOpenBlueTooth();
        }else{
            btnDisconnectServer.setVisibility(View.GONE);
        }

        //进来先判断是不是连接状态
        if (DeviceManage.getInstance().isConnected()) {
            whenConnectedState();
        }

        //蓝牙开启成功和关闭成功监听
        blueToothBroadcastReceiver.setBlueToothOperateListener(new IBlueToothOperateListener() {
            @Override
            public void openedBlueTooth() {
                //成功开启蓝牙后
                whenOpenBlueTooth();
            }
            @Override
            public void closedBlueTooth() {
                //成功关闭蓝牙后
                whenCloseBlueTooth();
            }
        });

        //蓝牙配对状态监听
        blueToothBroadcastReceiver.setBlueToothBondListener(new IBondStateListener() {
            @Override
            public void bonded() {
                showToast(R.string.bond_bonded);
                if (connectAnim != null) {
                    stopConnectAnim();
                }
                startRealConnect(device);
                //开始显示连接对话框
                showConnectioningDialog();
            }

            @Override
            public void bonding() {
                showToast(R.string.bond_bonding);
            }

            @Override
            public void bondNone() {
                showToast(R.string.bond_none);
                if (connectAnim != null) {
                    stopConnectAnim();
                    btnConnectServer.setEnabled(true);
                }
            }
        });
    }


    //当蓝牙打开时做的操作，打开的话列表中显示以匹配的蓝牙信息
    private void whenOpenBlueTooth() {
        String address=SpUtils.obtain().getString(LAST_DEVICE);
        //改变按钮状态
        ivSwitchOpenBluetoothOff.setVisibility(View.GONE);
        ivSwitchOpenBluetoothOn.setVisibility(VISIBLE);
        //显示已配对的蓝牙item
        bondedDevices = mBtAdatper.getBondedDevices();
        Iterator<BluetoothDevice> iterator= bondedDevices.iterator();
        while(iterator.hasNext()){
            BluetoothDevice bluetoothDevice=iterator.next();
            if(bluetoothDevice.getAddress().equals(address)){
                device=bluetoothDevice;
            }
            adapter.add(bluetoothDevice);//因为适配器是ArrayAdapter
            adapter.notifyDataSetChanged();
        }
    }

    //当蓝牙关闭时做的操作
    private void whenCloseBlueTooth(){
        ivSwitchOpenBluetoothOff.setVisibility(View.VISIBLE);
        ivSwitchOpenBluetoothOn.setVisibility(View.GONE);
        if((sets!=null && adapter!=null)){
            adapter.clear();
            sets.clear();
        }
        whenOnClickDisconnect();
    }

    //当蓝牙连接成功时做的操作
    public void whenConnectedState(){
        btnSearchBlueTooth.setVisibility(View.GONE);
        btnConnectServer.setVisibility(View.GONE);
        btnDisconnectServer.setVisibility(VISIBLE);
        //当没有点击列表进行连接时，device代表的是上次保存的device
        if(device!=null){
            tvDeviceName.setText(device.getName());
        }

    }

    //注册蓝牙广播接受者
    public void registerBlueToothReceiver(){
        blueToothBroadcastReceiver=BlueToothBroadcastReceiver.getSingleton();
        //搜索设备监听
        blueToothBroadcastReceiver.setBlueToothDeviceFoundListener(new IBlueToothDeviceFoundListener() {

            @Override
            public void onBlueToothDeviceFound(BluetoothDevice device, Intent intent) {
                //地址和rssi
                rssi = Objects.requireNonNull(intent.getExtras()).getShort(BluetoothDevice.EXTRA_RSSI);//信号值
                SpUtils.obtain().save(device.getAddress(),rssi+"");
                if(sets.add(device)){//true表示元素添加成功，不是重复的数据
                    if(device.getName()!=null && device.getAddress()!=null){
                        adapter.add(device);//因为适配器是ArrayAdapter
                        adapter.notifyDataSetChanged();
                    }
                }
            }
            @Override
            public void onBlueToothSearching() {
                //防止连接过程中
                if(connectioningDialogFragment!=null){
                    if(connectioningDialogFragment.isVisible()){
                        return;
                    }
                }
                btnSearchBlueTooth.setVisibility(View.GONE);
                btnStopSearchBlueTooth.setVisibility(VISIBLE);
                searchAnim= AnimationUtils.loadAnimation(context, R.anim.anim_round_rotate);
                LinearInterpolator interpolator = new LinearInterpolator();  //设置匀速旋转，在xml文件中设置会出现卡顿
                searchAnim.setInterpolator(interpolator);
                if (searchAnim != null) {
                    btnConnectServer.setEnabled(false);
                    tvLoading.setText(R.string.searching_title);
                    flLoading.setVisibility(VISIBLE);
                    ivLoading.startAnimation(searchAnim);  //开始动画
                }
            }

            @Override
            public void onBlueToothSearched() {
                //防止连接过程中
                if(connectioningDialogFragment!=null){
                    if(connectioningDialogFragment.isVisible()){
                        return;
                    }
                }
                btnStopSearchBlueTooth.setVisibility(View.GONE);
                if (searchAnim != null) {
                    btnSearchBlueTooth.setVisibility(VISIBLE);
                    btnConnectServer.setEnabled(true);
                    stopSearchAnim();
                }
            }
        });
    }

    //定位权限回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED ) {
                    // Permission Granted 授予权限
                    //处理授权之后逻辑
                    onClickSearchBlueTooth();
                }else{
                    showToast(R.string.tip_open_app_location);
                }
                break;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    }

    //停止搜索动画
    private void stopSearchAnim() {
        if (searchAnim != null) {
            searchAnim=null;
            flLoading.setVisibility(View.GONE);
            ivLoading.clearAnimation();
        }
    }

    //停止连接动画--指的是配对过程中的动画
    private void stopConnectAnim() {
        if (connectAnim != null) {
            connectAnim=null;
            flLoading.setVisibility(View.GONE);
            ivLoading.clearAnimation();
        }
    }

    public void whenOnClickDisconnect(){
        //防止正在搜索过程中，显示取消搜索，在显示搜索按钮
        if(btnStopSearchBlueTooth.getVisibility()!=VISIBLE){
            btnSearchBlueTooth.setVisibility(VISIBLE);
        }
        btnDisconnectServer.setVisibility(View.GONE);
        btnConnectServer.setVisibility(VISIBLE);
        tvDeviceName.setText(R.string.text_no_device);
        EventBus.getDefault().postSticky(new ShowDeviceNameEvent(null));
        EventBus.getDefault().removeAllStickyEvents();//移除所有的粘性事件
    }

    public void onClickSearchBlueTooth(){
        //判断系统是不是关闭了系统的位置服务
        if(!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            // 未打开位置开关，提示用户或做相应处理
            showToast(R.string.tip_open_location);
            return;
        }
        whenOnClickDisconnect();
        if(adapter!=null){
            adapter.setCurrentItem(-1);
            adapter.setmIsClick(false);
            adapter.notifyDataSetChanged();
        }
        if(sets!=null && adapter!=null){
            adapter.clear();
            sets.clear();
        }
        operateBlueTooth.searchBlueTooth();
    }

    //连接服务器
    public void connectToServer(){
        if (!mBtAdatper.isEnabled()) {
            showToast(R.string.open_bluetooth);
            return;
        }
        if(device!=null){
            //开始配对
            if(operateBlueTooth.getBondState(device)){//已经成功匹配过，直接开始显示连接对话框
                //真正开始连接
                startRealConnect(device);
                //开始显示连接对话框
                showConnectioningDialog();
            }else{//开始匹配，显示进度
                startConnectAnim();
            }
        }else{
            showToast(R.string.choose_device);
        }
    }

    //真正进行连接
    private void startRealConnect(BluetoothDevice device) {
        SpUtils.obtain().save(ISFRAGMENT,true);
        String strDeviceName = String.format("%s|%s", device.getName(), device.getAddress());
        DeviceManage.getInstance().setSelectedDevice(strDeviceName);
        DeviceManage.getInstance().connect();
    }

    //开始连接动画
    public void startConnectAnim(){
        connectAnim = AnimationUtils.loadAnimation(context, R.anim.anim_round_rotate);
        LinearInterpolator interpolator = new LinearInterpolator();  //设置匀速旋转，在xml文件中设置会出现卡顿
        connectAnim.setInterpolator(interpolator);
        if (connectAnim != null) {
            btnConnectServer.setEnabled(false);
            tvLoading.setText(R.string.connecting_title);
            flLoading.setVisibility(VISIBLE);
            ivLoading.startAnimation(connectAnim);  //开始动画
        }
    }

    //显示连接对话框
    public void showConnectioningDialog(){
        //开始显示连接对话框
        btnConnectServer.setEnabled(false);
        connectioningDialogFragment = ConnectioningDialogFragment.getSingleton();
        if(!connectioningDialogFragment.isAdded()){
            connectioningDialogFragment.setCancelable(false);
            connectioningDialogFragment.show(activity.getFragmentManager(), "connectioning");
            connectioningDialogFragment.setClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //点击取消--对话框消息+断开服务器+移除全部事件
                    DeviceManage.getInstance().setAutoDisconnect(false);
                    SpUtils.obtain().save(ISCLICKCANNEL,true);
                    dismissDialog();
                    DeviceManage.getInstance().disConnect();
                    showToast(R.string.connect_fail);
                }
            });
        }
    }

    //消失对话框
    public void dismissDialog(){
        btnConnectServer.setEnabled(true);
        if (connectioningDialogFragment != null && connectioningDialogFragment.isVisible()) {
            connectioningDialogFragment.dismissAllowingStateLoss();
        }
    }

    private void onClickBtnDisConnect() {
        DeviceManage.getInstance().setAutoDisconnect(false);
        DeviceManage.getInstance().disConnect();
        whenOnClickDisconnect();
    }


    //当Activity与fragment建立关联时调用
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context=context;
        activity= (Activity) context;
    }


    @Override
    protected int getLayoutId() {
        return R.layout.layout_fragment_equipment_communication_setup;
    }

    @Override
    protected void initView(View view) {
        ivCommonBack=view.findViewById(R.id.iv_common_back);
        tvCommonTitle=view.findViewById(R.id.tv_common_title);
        tvDeviceName=view.findViewById(R.id.tv_device_name);
        btnDisconnectServer = view.findViewById(R.id.btn_disconnect);
        btnConnectServer = view.findViewById(R.id.btn_connect);
        ivSwitchOpenBluetoothOn = view.findViewById(R.id.iv_switch_open_bluetooth_on);
        ivSwitchOpenBluetoothOff = view.findViewById(R.id.iv_switch_open_bluetooth_off);
        btnSearchBlueTooth = view.findViewById(R.id.btn_search);
        btnStopSearchBlueTooth = view.findViewById(R.id.btn_stop_search);
        btnGiveupBond = view.findViewById(R.id.btn_giveup_bond);
        listView =  view.findViewById(R.id.listView);
        ivLoading = view.findViewById(R.id.iv_loading);
        tvLoading = view.findViewById(R.id.tv_loading_title);
        flLoading = view.findViewById(R.id.fl_loading);

    }

    @Override
    protected void initListener(View view) {
        btnSearchBlueTooth.setOnClickListener(this);
        btnStopSearchBlueTooth.setOnClickListener(this);
        ivSwitchOpenBluetoothOn.setOnClickListener(this);
        ivSwitchOpenBluetoothOff.setOnClickListener(this);
        btnConnectServer.setOnClickListener(this);
        btnDisconnectServer.setOnClickListener(this);
        ivCommonBack.setOnClickListener(this);
        btnGiveupBond.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        btnConnectServer.setEnabled(true);
        if(v==ivCommonBack){
            backTo();
        }else if(v== btnConnectServer){
            isClickBtnConnectServer=true;
            if(flLoading.getVisibility()==VISIBLE)
                return;
            connectToServer();
        }else if(v== btnDisconnectServer){
            onClickBtnDisConnect();
        }else if ( v == btnSearchBlueTooth) {
            if(operateBlueTooth.requestPermission()){
                onClickSearchBlueTooth();
            }
        } else if ( v == btnStopSearchBlueTooth) {
            operateBlueTooth.stopSearchBlueTooth();
        }else if ( v == ivSwitchOpenBluetoothOff ) {
            operateBlueTooth.openBlueTooth();
        }else if ( v == ivSwitchOpenBluetoothOn ) {
            operateBlueTooth.closeBlueTooth();
        }else if(v==btnGiveupBond){//取消配对

        }
    }

    @Override
    protected void createPresenter(List<BasePresenter> mPresenters) {

    }

    @Override
    public void onDestroy() {
        if(sets!=null){
            sets.clear();
        }
        stopSearchAnim();
        stopConnectAnim();
        super.onDestroy();
    }
}
